Android

LiveData (android developers)

 

 

LiveData Overview

 

https://developer.android.com/topic/libraries/architecture/livedata

 


 

LiveData 는 관찰 가능한 데이터 홀더 클래스입니다.
일반적인 observable 와 다르게 LiveData 는 수명 주기를 인식합니다.
즉, 액티비티, 프래그먼트, 서비스와 같은 다른 앱 컴퍼넌트들의 수명주기를 고려합니다.
이러한 수명 주기 인식을 통해 LiveData는 active 수명주기 상태에 있는 앱 컴퍼넌트 observer 만을 업데이트합니다.

 

LIveData 는 수명주기가 STARTED 또는 RESUMED 상태일 때 observer (Observer class) 를 active 상태로 파악합니다.
LiveData 는 active 상태인 observer 에게만 업데이트를 알립니다.

 

 

Work with LiveData objects

 

1. 특정 데이터를 담은 LiveData 객체를 생성합니다. 보통 ViewModel 클래스에 있습니다.
2. onChanged() 메소드를 정의하는 Observer 객체를 생성합니다. 보통 UI controller (activity 또는 fragment) 에 생성합니다.
3. observe() 메서드를 이용해서 Observer 객체를 LiveData 객체에 연결합니다. observe() 메서는 LifecycleOwner 객체를 가집니다.

 

 

Create LiveData objects

 

public class NameViewModel extends ViewModel {

// Create a LiveData with a String
private MutableLiveData<String> currentName;

    public MutableLiveData<String> getCurrentName() {
        if (currentName == null) {
            currentName = new MutableLiveData<String>();
        }
        return currentName;
    }

// Rest of the ViewModel...
}

 

 

Observe LiveData objects

 

public class NameActivity extends AppCompatActivity {

    private NameViewModel model;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Other code to setup the activity...

        // Get the ViewModel.
        model = new ViewModelProvider(this).get(NameViewModel.class);

        // Create the observer which updates the UI.
        final Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newName) {
                // Update the UI, in this case, a TextView.
                nameTextView.setText(newName);
            }
        };

        // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
        model.getCurrentName().observe(this, nameObserver);
    }
}

 

 

Update LiveData objects

 

button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        String anotherName = "John Doe";
        model.getCurrentName().setValue(anotherName);
    }
});

 

 

LiveData 는 저장된 데이터를 업데이트하는 메서드가 없습니다.
MutableLiveData 클래스는 LiveData 객체에 저장된 값을 편집하기 위해서 setValue(T) 와 postValue(T) 메서드를 노출합니다.
다음 예제에서처럼 유저가 버튼을 클릭한다면 LiveData 의 값을 업데이트하고 모든 observer 들을 호출합니다.

 

button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        String anotherName = "John Doe";
        model.getCurrentName().setValue(anotherName);
    }
});

 

메인스레드에서 LiveData 객체를 업데이트 한다면 setValue(T) 를 호출합니다.
워커스레드에서 실행된다면 postValue(T)를 호출합니다.

 

 

Extend LiveData

 

public class StockLiveData extends LiveData<BigDecimal> {
    private StockManager stockManager;

    private SimplePriceListener listener = new SimplePriceListener() {
        @Override
        public void onPriceChanged(BigDecimal price) {
            setValue(price);
        }
    };

    public StockLiveData(String symbol) {
        stockManager = new StockManager(symbol);
    }

    @Override
    protected void onActive() {
        stockManager.requestPriceUpdates(listener);
    }

    @Override
    protected void onInactive() {
        stockManager.removeUpdates(listener);
    }
}

 

The onActive() method is called when the LiveData object has an active observer. This means you need to start observing the stock price updates from this method.
The onInactive() method is called when the LiveData object doesn’t have any active observers. Since no observers are listening, there is no reason to stay connected to the StockManager service.
The setValue(T) method updates the value of the LiveData instance and notifies any active observers about the change.

 

 

public class MyFragment extends Fragment {
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        LiveData<BigDecimal> myPriceListener = ...;
        myPriceListener.observe(getViewLifeycleOwner(), price -> {
            // Update the UI.
        });
    }
}

 

LiveData 객체는 수명주기를 인식합니다.
따라서 액티비티, 프래그먼트, 서비스 사이에서 LiveData 객체를 공유할 수 있습니다.
다음 예제는 싱글톤으로 구현합니다.

 

public class StockLiveData extends LiveData<BigDecimal> {
    private static StockLiveData sInstance;
    private StockManager stockManager;

    private SimplePriceListener listener = new SimplePriceListener() {
        @Override
        public void onPriceChanged(BigDecimal price) {
            setValue(price);
        }
    };

    @MainThread
    public static StockLiveData get(String symbol) {
        if (sInstance == null) {
            sInstance = new StockLiveData(symbol);
        }
        return sInstance;
    }

    private StockLiveData(String symbol) {
        stockManager = new StockManager(symbol);
    }

    @Override
    protected void onActive() {
        stockManager.requestPriceUpdates(listener);
    }

    @Override
    protected void onInactive() {
        stockManager.removeUpdates(listener);
    }
}

 

 

Transform LiveData

 

Transformations.map()

다음 예제는 userLiveData 의 값이 변경되면 Transfomations.map 을 거쳐서 userName 의 observer 을 호출합니다.

LiveData<User> userLiveData = ...;
LiveData<String> userName = Transformations.map(userLiveData, user -> {
    user.name + " " + user.lastName
});
userName.observe(this, price -> ...);

 

 

Transformations.switchMap()

// map 과 같지만 LiveData 객체를 반환합니다.

private LiveData<User> getUser(String id) {
  ...;
}

LiveData<String> userId = ...;
LiveData<User> user = Transformations.switchMap(userId, id -> getUser(id) );

 

 

Related posts

Leave a Comment